/*******************************************************************************
 * Fichero:     Cliente.java
 * Versión:     1.0
 * Autor:       Luis Maqueda
 * Fecha:       Mayo 2009
 * Proyecto:    AELANsoft cumpleaños
 * Descripción: Clase cliente: Crea el Cliente de la aplicación. Para establecer
 *la conexión con el Servidor, se necesitan: su dirección IP, el
 *puerto RMI y el nombre del objeto remoto. Si se obtiene con
 *éxito la referencia del objeto remoto, se lanzá la interfaz
 *gráfica de la aplicación, es decir, la aplicación en si. En caso
 *contrario se informara del error.
 ******************************************************************************/
package rmi;

import java.rmi.*;
import utiles.Usuario;
import utiles.VectorPersonas;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/******************************************************************************/
public class Cliente {
/******************************************************************************/

   private InterfazRemotaServidor servidorRemoto;
   private Usuario usuario;
   
   /***************************************************************************
    * Se obtiene una referencia remota del objeto servidor. En caso de aparecer
    * un error el método devuelve el entero correspondiente a su código de
    * error.
    * @param ip Direccion IP del servidor
    * @param puerto Puerto RMI
    * @param nombre Nombre del objeto remoto
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int ConectarServidor(String ip, String puerto, String nombre) {
      try {
         // Lugar en el que está el objeto remoto.
         servidorRemoto = (InterfazRemotaServidor)Naming.lookup("//" + ip +
            ":" + puerto + "/" + nombre);
         return 0;
      }
      catch (Exception e) {
         return 6;
      }
   }

   /***************************************************************************
    * Realiza la desconexión del cliente con el Servidor. En caso de aparecer
    * un error el	método devuelve el entero correspondiente a su código de
    * error.
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int DesconectarServidor() {
      try {
         servidorRemoto = null;
         return 0;
      }
      catch (Exception e) {
         return 7;
      }
   }

   /***************************************************************************
    * Comprueba que los datos de entrada sean correctos, en caso que sean
    * correctos, se procede a registrar al usuario en la base de datos llamando
    * al método IntroducirUsuario() del Servidor. En caso de aparecer un error
    * el método devuelve el entero correspondiente a su código de error.
    * @param nombre Nombre del usuario.
    * @param apellidos Apellidos del usuario.
    * @param correo Direccion de correo electronico del usuario.
    * @param contrasena Contraseña de acceso del usuario.
    * @param contrasena2 Contrasena de acceso del usuario.
    * @param dia Dia de cumpleaños del usuario.
    * @param mes Mes de cumpleaños del usuario.
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int Registro(String nombre, String apellidos, String correo,
      String contrasena, String contrasena2, int dia, int mes) {
      // Variables
      int estado;

      if (!ComprobarNombre(nombre)) {
         return 18;
      }
      else if (!ComprobarApellidos(apellidos)) {
         return 19;
      }
      else if (!ComprobarCorreo(correo)) {
         return 20;
      }
      else if (!ComprobarContrasena(contrasena, contrasena2)) {
         return 22;
      }
      else if (!ComprobarFecha(dia, mes)) {
         return 11;
      }
      else {
         try {
            estado = servidorRemoto.IntroducirUsuario(nombre, apellidos, correo,
                  contrasena, dia, mes);
            if (estado == 4 || estado == 8) {
               return estado;
            }
            else {
               this.usuario = new Usuario(correo, this);
               return usuario.AmigosUsuario();
            }
         }
         catch (Exception e) {
            // ha fallado la invocación remota
            return 6;
         }
      }
   }

   /***************************************************************************
    * Comprueba que la longitud del correo y contraseña sea distinta de 0, si
    * no da error y devuelve el código de error correspondiente. Realiza la
    * llamada al método ValidarUsuario() del Servidor para comprobar si dicho
    * usuario es correcto. En caso de serlo, crea la instancia de la clase
    * usuario. En caso de error devuelve el código de error correspondiente.
    * @param correo Direccion de correo electrónico del usuario
    * @param contrasena Contraseña de acceso del usuario
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int LoguearUsuario(String correo, String contrasena) {
     // Variables
     int estado;

      if (correo.length() == 0) {
         return 23;
      }
      else if (contrasena.length() == 0) {
         return 24;
      }
      else {
         try {
            estado = servidorRemoto.ValidarUsuario(correo, contrasena);
            if (estado == 5 || estado == 8) {
               return estado;
            }
            else {
               this.usuario = new Usuario(correo, this);
               return usuario.AmigosUsuario();
            }
         }
         catch (Exception e) {
            return 6;
         }
      }
   }

   /***************************************************************************
    * Obtiene la lista de amigos del usuario cuyo correo es "correo" invocando
    * al método ListarAmigos() del Servidor. En caso de error devuelve el
    * código de error correspondiente.
    * @param correo Direccion de correo electrónico del usuario
    * @param amigos Vector que contiene los amigos del usuario
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int ListarAmigos(String correo, VectorPersonas amigos) {
      try {
         VectorPersonas aux = new VectorPersonas();
         aux = servidorRemoto.ListarAmigos(correo);
         amigos.clear();
         for(int i=0; i<aux.size(); i++) {
            amigos.add(aux.get(i));
         }
         if (amigos == null) {
            // error
            return 6;
         }
         return 0;
      }
      catch (Exception e) {
         return 6;
      }
   }

   /***************************************************************************
    * Realiza la búsqueda correspondiente a datos invocando al método
    * BuscarAmigos() del servidor almacenando dicha búsqueda en el vector
    * amigos. En caso de error devuelve el código de error correspondiente.
    * @param correo Direccion de correo electrónico del usuario
    * @param datos Datos de búsqueda
    * @return Codigo de error. En caso de exito devuelve 0.
    **************************************************************************/
   public int RealizarBusqueda(String correo, String datos) {
      if (!ComprobarBusqueda(datos)) {
         // datos incorrectos en la búsqueda
         return 25;
      }
      try {
         VectorPersonas aux = new VectorPersonas();
         aux = servidorRemoto.BuscarAmigos(correo, datos);
         if (aux == null) {
            return 6;
         }
         else {
            usuario.RealizarBusqueda(aux);
            return 0;
         }
      }
      catch (Exception e) {
         return 6;
      }
   }

   /***************************************************************************
    * Devuelve verdadero si la longitud del nombre está entre 2 y 20
    * caracteres.
    * @param nombre Nombre del usuario
    * @return true si longitud(nombre) >= 2 && longitud(nombre) <= 20. En otro
    * caso devueve false
    **************************************************************************/
   public boolean ComprobarNombre(String nombre) {
      return nombre.length() >= 2 && nombre.length() <= 20;
   }

   /***************************************************************************
    * Devuelve verdadero si la longitud de apellidos está entre 2 y 50
    * caracteres.
    * @param apellidos Apellidos del usuario
    * @return true si longitud(apellidos)>=2 && longitud(apellidos) <= 50. En
    * otro caso devueve false
    **************************************************************************/
   public boolean ComprobarApellidos(String apellidos) {
      return apellidos.length() >= 2 && apellidos.length() <= 50;
   }

   /***************************************************************************
    * Devuelve verdadero si la longitud del nombre está entre 5 y 30 caracteres
    * y cumple con la estructura del correo electrónico. La estructura del
    * correo electrónico en sintaxis de Flex es:
    * (carácter)+'@'(carácter)+'.'(carácter)+.
    * @param correo Direccion de correo electrónico del usuario
    * @return true si longitud(correo)>= 5 && longitud(correo) <=30 &&
    * formatoCorrecto. En otro caso devueve false
    **************************************************************************/
   public boolean ComprobarCorreo(String correo) {
      if (correo.length() >= 5 && correo.length() <= 30 &&
         correo.matches("\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,4})+")) {
         return true;
      }
      else {
         return false;
      }
   }

   /***************************************************************************
    * Devuelve verdadero si la longitud de la contraseña1 está entre 6 y 12
    * caracteres y contraseña1 es igual a contraseña2.
    * @param contrasena1 contraseña del usuario
    * @param contrasena2 contraseña del usuario
    * @return true si longitud(contraseña)>=6 && longitud(contraseña) <=12) &&
    * contraseña==contraseña 2. En otro caso devueve false
    **************************************************************************/
   public boolean ComprobarContrasena(String contrasena1, String contrasena2) {
      return contrasena1.length() >= 6 && contrasena1.length() <= 12 &&
            contrasena1.compareTo(contrasena2) == 0;
   }

   /***************************************************************************
    * Devuelve verdadero si la fecha es válida, es decir, que mes este
    * comprendido entre 1 y 12 ,ambos inclusive; que dia este comprendido entre
    * 1 y 31, ambos inclusive, siempre y cuando sea correcto para el mes
    * introducido, es decir, dia=29 y mes=2 es una fecha incorrecta.
    * @param dia Día del mes
    * @param mes Mes del año
    * @return true si el valor de dia corresponde con el número de días del mes
    * En otro caso devueve false.
    **************************************************************************/
   public boolean ComprobarFecha(int dia, int mes) {
      if (mes == 1 || mes == 3 || mes == 5 || mes == 7 ||
         mes == 8 || mes == 10 || mes == 12) {
         return (dia > 0 && dia <= 31);
      }
      else if (mes == 4 || mes == 6 || mes == 9 || mes == 11) {
         return (dia > 0 && dia <= 30);
      }
      else if (mes == 2) {
         return (dia > 0 && dia <= 29);
      }
      else {
         // mes incorrecto
         return false;
      }
   }

   /***************************************************************************
    * Devuelve verdadero si la cadena “busq” contiene al menos tres caracteres
    * unidos y no son espacio en blanco y tiene una longitud menor o igual que
    * 50.
    * @param busq Datos de búsqueda
    * @return true si el valor “busq” contiene al menos tres caracteres
    * unidos y no son espacio en blanco y tiene una longitud menor o igual que
    * 50
    **************************************************************************/
   public boolean ComprobarBusqueda(String busq) {
      if (busq.length() < 3 || busq.length() >= 50) {
         return false;
      }
      else {
         if (busq.startsWith("   ")) {
            return false;
         }
         else {
            return true;
         }
      }
   }

   /***************************************************************************
    * Se añade el usuario de correo electrónico “correoA” a la lista de amigos
    * del usuario de correo electrónico “correoU” invocando al método
    * AñadirAmigo() del Servidor. En caso de error devuelve el código de error
    * correspondiente.
    * @param correoU Correo del usuario que añade al amigo
    * @param correoA Correo del amigo a añadir
    * @return true si el valor “busq” contiene al menos tres caracteres
    * unidos y no son espacio en blanco y tiene una longitud menor o igual que
    * 50
    **************************************************************************/
   public int AnadirAmigo(String correoU, String correoA) {
      try {
         return servidorRemoto.AnadirAmigo(correoU, correoA);
      }
      catch (Exception e) {
         return 6;
      }
   }

   /***************************************************************************
    * Devuelve la variable de clase "usuario"
    * @return usuario usuario identificado en el sistema
    **************************************************************************/
   public Usuario GetUsuario() {
      return this.usuario;
   }

}
